﻿namespace MvcXRepairCustomer.Services
{
    using System;
    using System.Collections.Generic;
    using MvcXRepairCustomer.Interfaces;
    using MvcXRepairCustomer.Repository.SQL;
    using XRepair.Models;
    using System.Security.Cryptography;
    using XRepair.Conventions.Enum;
    using MvcXRepair.ViewModel;
    using System.Net.Mail;
    using System.Net;

    public class UserService : IUserService
    {
        private UserDAO _userRepository;

        public UserService()
        {
            _userRepository = new UserDAO();
        }

        public bool AddNewUser(User user)
        {
            user.CreatedAt = DateTime.Now;

            RandomNumberGenerator rng = new RNGCryptoServiceProvider();
            byte[] tokenData = new byte[32];
            rng.GetBytes(tokenData);
            user.ActivationCode = Convert.ToBase64String(tokenData).Replace('/', '~');

            user.RoleID = (int)UserPermission.NormalUser;

            bool userAdded = _userRepository.AddNewUser(user);

            if (userAdded)
            {
                SendActivationEmail(user.EmailAddress, user.ActivationCode);
            }

            return userAdded;
        }

        public User GetUserInfoByCredentials(LoginViewModel model)
        {
            return _userRepository.GetUserInfoByCredentials(model.Email, model.Password);
        }

        public bool ActivateUserAccount(string actionvationCode)
        {
            return _userRepository.ActivateUserAccount(actionvationCode);
        }

        public bool IsUsernameOccupied(string username)
        {
            return _userRepository.IsUsernameOccupied(username);
        }

        public bool IsEmailOccupied(string email)
        {
            return _userRepository.IsEmailOccupied(email);
        }

        public bool UpdateUserPasswordByEmailAddress(string email)
        {
            RandomNumberGenerator rng = new RNGCryptoServiceProvider();
            byte[] tokenData = new byte[32];
            rng.GetBytes(tokenData);
            string newPassword = Convert.ToBase64String(tokenData);

            var isUpdated = _userRepository.UpdateUserPasswordByEmailAddress(email, newPassword);
            var isSent = SendResetPasswordEmail(email, newPassword);

            return isUpdated && isSent;
        }

        public bool ChangeUserPasswordByEmailAddress(string email, string newPassword)
        {
            return _userRepository.UpdateUserPasswordByEmailAddress(email, newPassword);
        }

        private bool SendResetPasswordEmail(string email, string newPassword)
        {
            try
            {
                var fromAddress = new MailAddress("xrepairmailservice@gmail.com", "xRepair");
                var toAddress = new MailAddress(email, "To Name");
                const string fromPassword = "xrepair24/7";
                const string subject = "Activate account on xrepair.net";

                string body = string.Format("Login email: {0}, password: {1}", email, newPassword);

                var smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com",
                    Port = 587,
                    EnableSsl = true,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = false,
                    Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
                };
                using (var message = new MailMessage(fromAddress, toAddress)
                {
                    Subject = subject,
                    Body = body
                })
                {
                    smtp.Send(message);
                }

                return true;
            }
            catch
            {
                // Handle send mail exception
                return false;
            }
        }

        private static void SendActivationEmail(string address, string activationCode)
        {
            try
            {
                var fromAddress = new MailAddress("xrepairmailservice@gmail.com", "xRepair");
                var toAddress = new MailAddress(address, "To Name");
                const string fromPassword = "xrepair24/7";
                const string subject = "Activate account on xrepair.net";

                string activationUrl = string.Join(null, new string[] { "http://localhost:37770/", "User/Activate/", activationCode });

                string body = activationUrl;

                var smtp = new SmtpClient
                {
                    Host = "smtp.gmail.com",
                    Port = 587,
                    EnableSsl = true,
                    DeliveryMethod = SmtpDeliveryMethod.Network,
                    UseDefaultCredentials = false,
                    Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
                };
                using (var message = new MailMessage(fromAddress, toAddress)
                {
                    Subject = subject,
                    Body = body
                })
                {
                    smtp.Send(message);
                }
            }
            catch
            {
                // Handle send mail exception
            }
        }
    }
}
